<?php

namespace modules\alioss;

use think\App;
use OSS\OssClient;
use AlibabaCloud\SDK\Sts\V20150401\Sts;
use AlibabaCloud\SDK\Sts\V20150401\Models\AssumeRoleRequest;
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
use \Exception;
use AlibabaCloud\Tea\Exception\TeaError;
use think\facade\Event;
use app\common\model\Config;
use app\common\model\Attachment;

class Alioss
{
    public function AppInit()
    {
        // 上传配置初始化
        Event::listen('uploadConfigInit', function (App $app) {
            $uploadConfig = get_sys_config('', 'upload');
            if ($uploadConfig['upload_mode'] == 'alioss') {
                $cdn = $uploadConfig['upload_cdn_url'] == '' ? 'http://'.$uploadConfig['upload_bucket'].'.'.$uploadConfig['upload_url'].'.aliyuncs.com' : $uploadConfig['upload_cdn_url'];
                $params = self::getSts();
                $app->request->upload = [
                    'cdn'    => $cdn,
                    'mode'   => $uploadConfig['upload_mode'],
                    'params' => $params
                ];
            }
        });

        // 附件管理中删除了文件
        Event::listen('AttachmentDel', function (Attachment $attachment) {
            if ($attachment->storage != 'alioss') {
                return true;
            }
            $uploadConfig = get_sys_config('', 'upload');
            if (!$uploadConfig['upload_access_key'] || !$uploadConfig['upload_secret_key'] || !$uploadConfig['upload_bucket']) {
                return true;
            }
            $OssClient          = new OssClient($uploadConfig['upload_access_key'], $uploadConfig['upload_secret_key'], 'https://' .$uploadConfig['upload_url'].'.aliyuncs.com');
            $url                = str_replace(full_url(), '', ltrim($attachment->url, '/'));
            $OssClient->deleteObject($uploadConfig['upload_bucket'], $url);
            return true;
        });
    }

    public static function getSts()
    {
        $uploadConfig = get_sys_config('', 'upload');
        try {
            $client = self::createClient();
            $assumeRoleRequest = new AssumeRoleRequest([
                "roleArn" => $uploadConfig['upload_RoleArn'],
                "roleSessionName" => $uploadConfig['upload_RoleSessionName']
            ]);
            $runtime = new RuntimeOptions([]);
            try {
                $createClient = $client->assumeRoleWithOptions($assumeRoleRequest, $runtime);
                $credentials = $createClient->body->credentials;
                $expiration = strtotime($credentials->expiration);
                return [
                    'accessKeyId' => $credentials->accessKeyId,
                    'accessKeySecret' => $credentials->accessKeySecret,
                    'securityToken' => $credentials->securityToken,
                    'expiration' => $expiration,
                    'region' => $uploadConfig['upload_url'],
                    'bucket' => $uploadConfig['upload_bucket'],
                    'error' => 0
                ];
            } catch (Exception $error) {
                if (!($error instanceof TeaError)) {
                    $error = new TeaError([], $error->getMessage(), $error->getCode(), $error);
                }
                return [
                    'params' => [
                        'error'    => 1,
                        'data'     => $error
                    ]
                ];
            }
        } catch (Exception $e) {
            return [
                'params' => [
                    'error'    => 2,
                    'data'     => [
                        'code' => '请填写云存储的相关信息！'
                    ]
                ]
            ];
        }
    }

    /**
     * 使用AK&SK初始化账号Client
     * @return Sts Client
     */
    public static function createClient(){
        $uploadConfig = get_sys_config('', 'upload');
        $config = new Config([
            "accessKeyId" => trim($uploadConfig['upload_access_key']),
            "accessKeySecret" => trim($uploadConfig['upload_secret_key'])
        ]);
        // 访问的域名
        $config->endpoint = $uploadConfig['upload_sts'];
        return new Sts($config);
    }

    public function enable()
    {
        Config::addConfigGroup('upload', '上传配置');
    }

    public function disable()
    {
        Config::whereIn('name', ['upload_mode', 'upload_bucket', 'upload_access_key', 'upload_secret_key', 'upload_url', 'upload_cdn_url', 'upload_RoleArn', 'upload_RoleSessionName', 'upload_sts'])->delete();
        Config::removeConfigGroup('upload');
    }
}